//
//  Problem859.swift
//  TestProject
//
//  Created by 毕武侠 on 2021/3/27.
//  Copyright © 2021 zhulong. All rights reserved.
//

import UIKit

/*
 859. 亲密字符串 【字符对比】
 给定两个由小写字母构成的字符串 A 和 B ，只要我们可以通过交换 A 中的两个字母得到与 B 相等的结果，就返回 true ；否则返回 false 。

 交换字母的定义是取两个下标 i 和 j （下标从 0 开始），只要 i!=j 就交换 A[i] 和 A[j] 处的字符。例如，在 "abcd" 中交换下标 0 和下标 2 的元素可以生成 "cbad" 。

 示例 1：
     输入： A = "ab", B = "ba"
     输出： true
     解释： 你可以交换 A[0] = 'a' 和 A[1] = 'b' 生成 "ba"，此时 A 和 B 相等。
 示例 2：
     输入： A = "ab", B = "ab"
     输出： false
     解释： 你只能交换 A[0] = 'a' 和 A[1] = 'b' 生成 "ba"，此时 A 和 B 不相等。
 示例 3:
     输入： A = "aa", B = "aa"
     输出： true
     解释： 你可以交换 A[0] = 'a' 和 A[1] = 'a' 生成 "aa"，此时 A 和 B 相等。
 示例 4：
     输入： A = "aaaaaaabc", B = "aaaaaaacb"
     输出： true
 示例 5：
     输入： A = "", B = "aa"
     输出： false
 提示：
     0 <= A.length <= 20000
     0 <= B.length <= 20000
     A 和 B 仅由小写字母构成。
 */
@objcMembers class Problem859: NSObject {
    func solution() {
        print(buddyStrings("ab", "ba"))
        print(buddyStrings("ab", "ab"))
        print(buddyStrings("aa", "aa"))
        print(buddyStrings("aaaaaaabc", "aaaaaaacb"))
    }
    
    /*
     1: a b的个数必须相等
     2: 遍历2个字符串，找到第一个不相等的字符  firstA = b[i] firstB = a[i]
     3: 继续遍历，找到第二个不相等的字符 判断firstA == a[j] && firstB == b[j]
     4: 创建一个dic:[Character: Int]记录a中每个字符的个数，为了处理ab 和 aa
     5: 当字符串a和b完全相同时，那么只要a中有2个相同的字符，就像替换，=> dic存在字符数量>1
     */
    func buddyStrings(_ a: String, _ b: String) -> Bool {
        if a.count != b.count {
            return false
        }
        var dic:[Character: Int] = [:]
        let chartsA = Array(a)
        let chartsB = Array(b)
        
        var firstA: Character? = nil
        var firstB: Character? = nil
        for i in 0..<chartsA.count  {
            dic[chartsA[i], default: 0] += 1
            if chartsA[i] !=  chartsB[i] {
                if firstA == nil {
                    firstA = chartsB[i]
                    firstB = chartsA[i]
                } else if firstA == chartsA[i] && firstB == chartsB[i] {
                    firstA = "?"
                    firstB = "?"
                } else {
                    return false
                }
            }
        }
        if firstA == nil {
            for value in dic.values {
                if value > 1 {
                    return true
                }
            }
            return false
        }
        return firstA == "?"
    }
}
